<?php

class template
{

    // {{{ getFilename

    public static function getFilename()
    {
        return controller::getTemplate() .
            config::get('mvc.template.extension');
    }

    // }}}
    // {{{ getFilepath

    public static function getFilepath()
    {
        return 
            config::get('mvc.templates.folder') .
            controller::getModel() .  
            DIRECTORY_SEPARATOR .
            self::getFilename();
    }

    // }}}
    // {{{ exists

    /**
     * checks if the template exists in the filesystem
     *
     * @return boolean
     * @access public
     */
    public static function exists()
    {
        return file_exists(self::getFilepath());
    }

    // }}}
    // {{{ raw

    public static function raw()
    {
        return file_get_contents(self::getFilepath());
    }

    // }}}
    // {{{ replace

    public static function replace($param, $value, $text)
    {
        $param_sintax = config::get('mvc.template.param.syntax');
        $regex = sprintf($param_sintax, preg_quote($param));
        // todo, verify this issue is bit buggy !
        settype($value, 'string');
        return preg_replace($regex, $value, $text);
    }

    // }}}
    // {{{ nested 

    /**
     * checks if the defined template contains subtemplates
     *
     * @return boolean
     * @access public
     */
    public function isNested()
    {
        $regex = config::get('mvc.template.including.syntax');
        return preg_match($regex, self::raw());
    }

    // }}}
    // {{{ load
    
    /**
     * recursive templete loader 
     *
     * gets the template and fully loads every subtemplate that is 
     * found in it
     * 
     * @static
     * @access  public
     * @return  void
     */
    public static function load()
    {
        $data = self::raw();
        $regex = config::get('mvc.template.including.syntax');

        if (preg_match_all($regex, $data, $configuration)) {

            foreach ($configuration[0] as $template_information) {
                $string_template_model = preg_replace(
                    '/[}{]/',
                    '',
                    $template_information
                );
                $array_template_model = split(',', $string_template_model);
                if (count($array_template_model) == 2) {
                    $template_to_load = $array_template_model[0];
                    $model_to_load = $array_template_model[1];
                    $data = preg_replace(
                        '/\{' .
                            preg_quote($template_to_load) . ',' .
                            preg_quote($model_to_load) .
                        '\}/',
                        'CWMWMWwmMW',
                        $data
                    );

                    $key = output::freeze();

                        controller::setTemplate($template_to_load);
                        controller::setModel($model_to_load);
                        $m = controller::load();

                        $output = controller::merge(
                            $m->getResults(),
                            template::load()
                        );

                        // $output = output::get();

                    output::melt($key);

                    $data = preg_replace('/CWMWMWwmMW/', $output, $data);
                }
            }
        }
        return $data;
    }

    // }}}
    // {{{ errors

    /**
     * will replace all the error ocurrences from the template compilin a human
     * readable error message or removing it defenetely from the template
     *
     * the aim and purpose of this code is to facilitate the operation between
     * programmers and designers. putting all the desing and error messages
     * apart from the code and letting desingers change the application in a
     * very easy to understand way.
     *
     * @param   string    $error_name     the object, name as it exists in the
     * template
     *
     * <code>
     * [!myError Hello this is my Error Foo cant be $foo! ]
     * <code>
     *
     * @param   array     $parameters     an array containing the error names as
     * keys and booleans as values.
     *
     * any found keys in the $parameters array should be replace by its
     * coreresponding error message, the replace function should be 
     * executed previously to this
     *
     * @param   string    $template       the template to be parsed
     * @return  string the aletered template with the errors that should be
     * shown and the the error messages that shouln'b be displayed must be
     * removed
     *
     */
    public function errors($parameters, $template)
    {
        if(empty($parameters)) {
            return preg_replace('/[\[][^\]]+[\]]/', '', $template);
        }

        // params that are set to 1 will display, any other will be removed
        // array( 'param' => 1, 'foo' => 0);
        foreach ($parameters as $param => $valid) {
            if ($valid === 1) {
                $replacement = "$2";
            } else {
                $replacement = '';
            }
            $template = preg_replace("/([[][!]" . $param .
                " )([^]]*)([\]])/",
                $replacement, $template);
        }
        return $template;
    }

    // }}}
    // {{{ merge

    public function merge($array, $rename = null, $data = null)
    {
        if ($data == null) {
            $data = self::load();
        }
        $return_string = '';
        $count = 1;
        foreach($array as $binding => $value) {
            if (is_array($value)) {
                $data = self::load();
                foreach(array_keys($value) as $key) {
                    if ($rename != null) {
                        $param = $rename;
                    } else {
                        $param = $key;
                    }
                    $data = self::replace(
                        $param, $array[$binding][$key], $data
                    );
                }
                $return_string .= $data;
            } else {
                if ($rename != null) {
                    $binding = $rename;
                }
                $return_string .= self::replace($binding, $value, $data);
            }
            $count ++;
        }
        if ($return_string != '') {
            return $return_string;
        }
        // $data = preg_replace('/\$\w+/', '', $data);
        return $data;
    }

    // }}}

}
?>
